Skip to content

ci: update ruff requirement from <0.14.0,>=0.13.0 to >=0.13.0,<0.17.0 - #562

Merged
liramon2 merged 4 commits into
mainfrom
dependabot/pip/ruff-gte-0.13.0-and-lt-0.17.0
Aug 3, 2026
Merged

ci: update ruff requirement from <0.14.0,>=0.13.0 to >=0.13.0,<0.17.0#562
liramon2 merged 4 commits into
mainfrom
dependabot/pip/ruff-gte-0.13.0-and-lt-0.17.0

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 3, 2026

Copy link
Copy Markdown
Contributor

Updates the requirements on ruff to permit the latest version.

Release notes

Sourced from ruff's releases.

0.16.1

Release Notes

Released on 2026-07-30.

Preview features

  • Add an option to opt out of human-readable names (#27160)
  • [flake8-pytest-style] Make fixes safe by default and unsafe only when comments are present (PT018) (#27201)
  • [pyupgrade] Skip fix when a defaulted TypeVar precedes a non-defaulted one (UP040, UP046, UP047) (#27133)
  • [ruff] Fix false positive with unpacked arguments (RUF065) (#26959)

Bug fixes

  • Bump gen-lsp-types to gracefully handle unknown enumeration values in LSP messages (#27230)
  • [flake8-bugbear] Mark range as immutable (B008) (#27247)
  • [flake8-comprehensions] NFKC-normalize keyword names in C408 fix (#26813)
  • [flake8-return] Fix false positive when variable is read in finally clause (RET504) (#25441)
  • [pydocstyle] Skip section detection inside RST directive bodies (D214, D405, D413) (#23635)
  • [refurb] Parenthesize yield arguments in the FURB192 fix (#27192)

Rule changes

  • [flake8-pytest-style] Mark PT022 fixes as unsafe (#26440)
  • [refurb] Mark fixes that remove unknown separators as unsafe (FURB105) (#27200)

Server

  • Fix indexing of excluded nested Ruff workspaces (#27303)
  • Lint TOML files in the LSP (#26862)

Documentation

  • Cover pycon Markdown formatting (#27153)
  • [flake8-bandit] Document TYPE_CHECKING exception (S101) (#27004)
  • [flake8-import-conventions] Document that extend-aliases can override default aliases (#27191)
  • [pylint] Add missing fix safety gotchas for non-augmented-assignment (PLR6104) (#27250)

Other changes

  • Reduce syntax error noise by swallowing dedents like indents (#27170)
  • Vendor latest annotate-snippets (#27033)

Contributors

... (truncated)

Changelog

Sourced from ruff's changelog.

0.16.1

Released on 2026-07-30.

Preview features

  • Add an option to opt out of human-readable names (#27160)
  • [flake8-pytest-style] Make fixes safe by default and unsafe only when comments are present (PT018) (#27201)
  • [pyupgrade] Skip fix when a defaulted TypeVar precedes a non-defaulted one (UP040, UP046, UP047) (#27133)
  • [ruff] Fix false positive with unpacked arguments (RUF065) (#26959)

Bug fixes

  • Bump gen-lsp-types to gracefully handle unknown enumeration values in LSP messages (#27230)
  • [flake8-bugbear] Mark range as immutable (B008) (#27247)
  • [flake8-comprehensions] NFKC-normalize keyword names in C408 fix (#26813)
  • [flake8-return] Fix false positive when variable is read in finally clause (RET504) (#25441)
  • [pydocstyle] Skip section detection inside RST directive bodies (D214, D405, D413) (#23635)
  • [refurb] Parenthesize yield arguments in the FURB192 fix (#27192)

Rule changes

  • [flake8-pytest-style] Mark PT022 fixes as unsafe (#26440)
  • [refurb] Mark fixes that remove unknown separators as unsafe (FURB105) (#27200)

Server

  • Fix indexing of excluded nested Ruff workspaces (#27303)
  • Lint TOML files in the LSP (#26862)

Documentation

  • Cover pycon Markdown formatting (#27153)
  • [flake8-bandit] Document TYPE_CHECKING exception (S101) (#27004)
  • [flake8-import-conventions] Document that extend-aliases can override default aliases (#27191)
  • [pylint] Add missing fix safety gotchas for non-augmented-assignment (PLR6104) (#27250)

Other changes

  • Reduce syntax error noise by swallowing dedents like indents (#27170)
  • Vendor latest annotate-snippets (#27033)

Contributors

... (truncated)

Commits
  • 80790b3 Bump 0.16.1 (#27330)
  • 63830f3 [ty] Borrow from constraint set storage less often (#27328)
  • f40dca9 [ty] Preserve forwarded expanded-variadic diagnostic sources (#27266)
  • 0d80497 Lint TOML files in the LSP (#26862)
  • d91586b Update prek dependencies (#27293)
  • 7da4b8b [ty] Respect bounds and constraints in generic materializations (#27228)
  • b20daf7 [ty] refactor: add helper function to send partial results (#27249)
  • 4d4c8fa [ty] Emit diagnostic when specializing a non-generic class (#26883)
  • 7c3e2db [ty] Fix enum class container assignability (#27318)
  • d5ef97f [flake8-return] Fix false positive when variable is read in finally claus...
  • Additional commits viewable in compare view

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Updates the requirements on [ruff](https://github.com/astral-sh/ruff) to permit the latest version.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](astral-sh/ruff@0.13.0...0.16.1)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.16.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file python Pull requests that update python code labels Aug 3, 2026
@dependabot
dependabot Bot requested a review from a team as a code owner August 3, 2026 13:45
@dependabot dependabot Bot added the dependencies Pull requests that update a dependency file label Aug 3, 2026
@dependabot
dependabot Bot requested a review from liramon2 August 3, 2026 13:45
@dependabot dependabot Bot added the python Pull requests that update python code label Aug 3, 2026
@dependabot
dependabot Bot requested a deployment to manual-approval August 3, 2026 13:50 Waiting
@liramon2

liramon2 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@strandly-the-agent review this PR by going through each dependency update and do an analysis if this PR is safe

@strandly-the-agent strandly-the-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TL;DR — this won't break the build, but <0.15.0 is the number you want, not <0.17.0. There's exactly one dependency here (ruff, in two places: pyproject.toml:73 and :130). I swept every ruff version the new range allows; the linter is clean on all of them and CI is green. The formatter is the catch — it changes style at 0.15.0, and this repo's pre-commit hook runs the formatter in fix mode.

What I actually verified (branch dependabot/pip/ruff-gte-0.13.0-and-lt-0.17.0 @ a78fa22):

  • ruff check exits 0 on all 44 versions in >=0.13.0,<0.17.0 — a real sweep, not a spot check, and sensitivity-controlled by injecting F401/E711 to confirm the sweep would have caught a regression.
  • ✅ Real CI on this SHA: call-test-lint / Lint, CI Gate and all 16 unit-test/dependency-check jobs SUCCESS. The rollup reads PENDING only because Secure Integration test / check-access-and-checkout sits on the usual bot-approval gate.
  • ✅ ruff 0.16.0's headline breaking change ("enables 413 rules by default, up from 59") does not reach this repo[tool.ruff.lint] select = ["E","F","I","B"] (pyproject.toml:206) is a closed allowlist, and because hatch-static-analysis.scripts are overridden with plain ruff check, hatch never injects its own ruff_defaults.toml.
  • ✅ Wheels and provenance: no regression — 17 py3-none-* wheels cover the whole 3.10–3.13 × linux/windows/macOS matrix, and ruff ships 0 PyPI attestations on both the current pin and 0.16.1 (symmetric, so not an argument against this PR).
  • 🟡 ruff format --check passes on 0.13.0–0.14.14 and first fails at exactly 0.15.0 (through 0.16.1), on 2 files. Details below; one inline comment on :73.

Questions

  • 🔶 (blocking-ish, the actual decision) Is widening past <0.15.0 deliberate? sdk-python and harness-sdk both pin ruff>=0.13.0,<0.15.0 today, and this repo's constraint exists because of a deliberate sync to sdk-python (#315: "I also synced ruff version with our sdk-python repository for consistency"). <0.15.0 restores that parity and stays clear of the formatter change in one move.
  • 🔷 (non-blocking) This PR and the 13 sibling Dependabot PRs (#552#565, all opened in the same ~95-second burst) don't reflect the .github/dependabot.yml merged 3 days earlier in #538 — no ci(python) prefix, no development-dependencies grouping, floor never raised (pure ceiling widening, i.e. the old widen behavior), and this one opened 4 days after ruff 0.16.1 shipped, inside both the 5-day default and 7-day minor cooldown. Expected transition staleness, or does Dependabot need a nudge to pick the new config up?
🟡 The formatter finding, in full — who hits it and how

Ruff's stable formatter style changed at 0.15.0 (lambda / conditional-expression parenthesization). On this tree that's 2 files:

0.13.0–0.14.14   ruff format --check → 141 files already formatted           (rc=0)
0.15.0–0.16.1    ruff format --check → 2 files would be reformatted, 139 ok  (rc=1)
--- tests/test_agent_core_memory.py     (line 20)
-        mock_client.side_effect = (
-            lambda service, **kwargs: mock_bedrock_agent_core if service == "bedrock-agentcore" else None
+        mock_client.side_effect = lambda service, **kwargs: (
+            mock_bedrock_agent_core if service == "bedrock-agentcore" else None
         )
--- tests/utils/test_generate_schema_util.py   (line 210)
-            side_effect=lambda obj, name: (False if name in ["invalid_operation", "InvalidOperation"] else True),
+            side_effect=lambda obj, name: False if name in ["invalid_operation", "InvalidOperation"] else True,

Nothing in CI goes red, and I checked rather than assumed: the only lint invocation repo-wide is .github/workflows/test-lint.yml:121hatch run test-linthatch fmt --linter --checklint-check = ruff check. No workflow runs a format check.

The cost lands on contributors instead. .pre-commit-config.yaml:4-10's hatch-format hook runs hatch fmt --formatter in fix mode with pass_filenames: false, using the env pinned at pyproject.toml:130:

$ printf '\n# unrelated edit\n' >> src/strands_tools/calculator.py && git add $_
$ pre-commit run hatch-format
Format code..............................................................Failed
- files were modified by this hook
3 files reformatted, 138 files left unchanged
$ git status --porcelain
MM src/strands_tools/calculator.py
 M tests/test_agent_core_memory.py             <-- unrelated
 M tests/utils/test_generate_schema_util.py    <-- unrelated

The commit is blocked, and the natural git add -A drags the churn into an unrelated PR. On main the same command is a no-op (141 files left unchanged). One thing bounds the blast radius: hatch does not re-sync an env whose pin is still satisfied — an existing hatch-static-analysis env created at 0.13.3 stays at 0.13.3 after checking out this branch, and only a fresh or pruned env resolves 0.16.1. So it's intermittent: new contributors and pruned envs hit it, long-lived envs don't. That's why this is 🟡 and not 🔴.

Two ways out, either is fine:

  1. Narrow to <0.15.0 (my suggestion inline) — matches the siblings, stays below the style change, nothing to reformat.
  2. Keep <0.17.0 and land the reformat herehatch env prune && hatch fmt --formatter produces exactly the 3-line diff above. If you go this way, also worth adding hatch run test-format to the lint job, since right now nothing enforces formatting in CI and that's what let the drift stay invisible.

(Editing the diff does mean Dependabot stops managing this branch — fine either way, just don't @dependabot recreate afterwards or the edit is overwritten.)

Appendix — 2 pre-existing items, not this PR's problem

Both are true with this PR closed, so they shouldn't gate it. Happy to file them as issues if useful — say the word.

  • pyproject.toml:203 — 22 files are silently unlinted. include lists "tests-integ/**/*.py" (hyphen) but the directory is tests_integ (underscore). Proof: 12 deliberate errors injected into tests_integ/utils/knowledge_base_util.py and ruff check still reported All checks passed!, while ruff check <that file> reported all 12. One-character fix.
  • pyproject.toml:66hatch>=1.16.5 has no upper bound, and test-lint.yml installs that then runs hatch run test-lint. hatch 1.17.1 already prints "The hatch fmt command is deprecated and will be removed in a future release". When hatch drops it, CI lint breaks with no PR to review — arguably a larger version risk than the bounded ruff range Dependabot keeps widening.

Reviewed by strandly-the-agent — an experimental AI agent built with Strands. Independent passes: dependency-safety sweep (44 versions), CI/workflow trace, repo-convention check. Worth a human eye before you act on it; the <0.15.0 call in particular is a judgment call about how closely tools should track sdk-python.

Comment thread pyproject.toml
Co-authored-by: Strandly (The Agent) <strands-agents+strandly@amazon.com>
@liramon2

liramon2 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@strandly-the-agent Apply the fix and push to this branch:
Keep <0.17.0 and land the reformat here — hatch env prune && hatch fmt --formatter produces exactly the 3-line diff above. If you go this way, also worth adding hatch run test-format to the lint job, since right now nothing enforces formatting in CI and that's what let the drift stay invisible.

@strandly-the-agent

Copy link
Copy Markdown
Contributor

Couldn't push — I only have READ on this repo (viewerPermission: READ, so git push → 403, and the API commit route is closed to me too). The change is done and verified locally; patches below, ~30 seconds to apply. Grant write or apply them and I'll stay out of the way.

Two things you need to know before applying:

1. I reverted your web-UI commit 27d8132. It set :73 to <0.15.0 but left :130 at <0.17.0, and your comment 2 minutes later said keep <0.17.0 — so I took the later instruction and restored :73 so both agree. Say the word if you'd rather go the other way (<0.15.0 in both places is still a one-line fix with zero reformat and zero blast radius).

2. I split the change in two, because the CI gate you asked for has a blast radius I don't think you want yet. Patch A is safe and ready. Patch B (the gate) would turn 43 of the 68 measurable open PRs red — 39 of them on files their authors never touched. Not because of anything in this PR: those heads already fail under the ruff their own pyproject.toml pins (0.13.3). pr-and-push.yml:19 checks out the PR head, not the merge result, and most branches predate the big reformat in #315 — so the gate would grade contributors on stale copies of your files. All 5 heads I sampled flip to green when merged with main. Three ways to fix it below.

Patch A — land this now (constraint coherence + the reformat, 3 lines of code)

Easiest path, no patch file needed — this reproduces commits 1+2 exactly:

git checkout dependabot/pip/ruff-gte-0.13.0-and-lt-0.17.0
git checkout a78fa22 -- pyproject.toml      # undo the partial suggestion: <0.17.0 in both places again
hatch env prune && hatch fmt --formatter    # the reformat (verified byte-identical to my diff)

Or apply directly:

diff --git a/pyproject.toml b/pyproject.toml
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -70,7 +70,7 @@ dev = [
     "mypy>=0.981,<1.0.0",
     "pre-commit>=3.2.0,<4.2.0",
     "pytest>=8.0.0,<10.0.0",
-    "ruff>=0.13.0,<0.15.0",
+    "ruff>=0.13.0,<0.17.0",
     "responses>=0.6.1,<1.0.0",
     "mem0ai>=0.1.104,<1.0.0",
     "opensearch-py>=2.8.0,<3.0.0",
diff --git a/tests/test_agent_core_memory.py b/tests/test_agent_core_memory.py
--- a/tests/test_agent_core_memory.py
+++ b/tests/test_agent_core_memory.py
@@ -20,8 +20,8 @@ def mock_boto3_client():
         mock_bedrock_agent_core = mock.MagicMock()
 
         # Configure boto3.client to return our mock
-        mock_client.side_effect = (
-            lambda service, **kwargs: mock_bedrock_agent_core if service == "bedrock-agentcore" else None
+        mock_client.side_effect = lambda service, **kwargs: (
+            mock_bedrock_agent_core if service == "bedrock-agentcore" else None
         )
 
         yield {
diff --git a/tests/utils/test_generate_schema_util.py b/tests/utils/test_generate_schema_util.py
--- a/tests/utils/test_generate_schema_util.py
+++ b/tests/utils/test_generate_schema_util.py
@@ -207,7 +207,7 @@ class TestCheckBoto3Validity:
         # Patch hasattr to return False for the operation
         with patch(
             "strands_tools.utils.generate_schema_util.hasattr",
-            side_effect=lambda obj, name: (False if name in ["invalid_operation", "InvalidOperation"] else True),
+            side_effect=lambda obj, name: False if name in ["invalid_operation", "InvalidOperation"] else True,
         ):
             # Mock the conversion functions
             with patch(

Verified on the result:

check result
ruff check + ruff format --check, all 44 ruff versions in >=0.13.0,<0.17.0 ✅ 44/44 pass
real CI commands hatch run test-lint / hatch run test-format ✅ both EXIT=0 (hatch 1.17.1, env resolved ruff 0.16.1)
the 2 touched test files 36 passed in 0.56s
reformat semantically neutral ✅ AST-identical (parens don't survive parsing — a lambda body already extends over the whole conditional expression)

The thing I got wrong in my first review, in your favour: I expected this to trade the skew for its mirror image (old ruff rejecting the new style). It doesn't — the new form is what 0.15+ requires and what every earlier version tolerates, so the tree is a fixed point across the entire allowed range. No floor bump needed.

Patch B — the CI gate, and why I'd hold it (43/68 open PRs go red)
diff --git a/.github/workflows/test-lint.yml b/.github/workflows/test-lint.yml
--- a/.github/workflows/test-lint.yml
+++ b/.github/workflows/test-lint.yml
@@ -119,4 +119,10 @@ jobs:
       - name: Run lint
         id: lint
         run: hatch run test-lint
+        continue-on-error: false
+
+      - name: Run format check
+        id: format
+        if: ${{ !cancelled() }}
+        run: hatch run test-format
         continue-on-error: false

(if: ${{ !cancelled() }} because steps are sequential — without it a lint failure skips the format check and contributors need two round trips to see both.)

Measured blast radius. For each of the 79 other open PRs I archived its head and ran ruff format --check with the newest ruff that head's own pyproject.toml:130 allows:

68 measurable      GREEN 25    RED 43
   of the 43 red:  fail only on files the PR never touched   25
                   mixed own + collateral                    14
                   fail only on their own code                4
11 unmeasurable — they pin ruff>=0.4.4,<0.5.0 (pre-#315); these would fail too

The collateral files are the same handful over and over: src/strands_tools/use_aws.py, tests/test_shell.py, tests/test_elasticsearch_memory.py, src/strands_tools/http_request.py. Concretely, saime428 on #529 would get a red build citing three files they never opened.

It's the checkout, not the code. These heads fail under ruff 0.13.3 — already allowed today — so this is pre-existing drift, unrelated to the version bump. The composition that bites: for a pull_request event the workflow definition comes from the merge commit, so every open PR picks up the new step on its next run with no rebase needed — but pr-and-push.yml:19 overrides the checkout with ref: ${{ github.event.pull_request.head.sha || github.sha }}, so the code under test is the stale head. New gate, old tree:

PR #549  head: 1 file would be reformatted    merge with main: 141 files already formatted
PR #529  head: 3 files would be reformatted   merge with main: 141 files already formatted
PR #543  head: 2 files would be reformatted   merge with main: 141 files already formatted
PR #522  head: 1 file would be reformatted    merge with main: 141 files already formatted
PR #475  head: 1 file would be reformatted    merge with main: 145 files already formatted

5/5 flip. The gate would be measuring branch staleness, not the contributor's work — and then the fix-mode hatch-format pre-commit hook rewrites those files into their next commit, which is the exact failure mode this PR set out to kill, just aimed at new victims.

Three ways forward, your call:

  1. Land A now, B as its own PR — cleanest. It's a separable concern and you raised it as an aside; in its own PR the fallout is deliberate and announceable.
  2. Scope the gate to the diffruff format --check $(git diff --name-only origin/main...HEAD -- '*.py'), so a stale branch is only judged on its own work. Needs fetch-depth: 0 on the checkout.
  3. Drop the ref: override so the job tests the merge result. Root-cause fix, and it makes the existing lint step more correct too — but test-lint.yml is a reusable workflow that release.yml also calls with inputs.ref, and persist-credentials: false plus an explicit head SHA reads like a deliberate supply-chain choice. Not mine to change.
Commit messages, if you want them

Three commits, cz check-clean, split so the reformat is reviewable on its own:

ci: keep the ruff ceiling at <0.17.0 in both constraints   (pyproject.toml)
style: adopt the formatter style ruff 0.15+ requires       (the 2 test files)
ci: enforce formatting in the lint job                     (test-lint.yml)  <- patch B

Two pre-existing things this does not fix, so nobody over-reads "CI now enforces formatting" — happy to file either as an issue:

  • pyproject.toml:203include says tests-integ (hyphen), the directory is tests_integ (underscore). 22 files are invisible to ruff check and to the new gate.
  • pyproject.toml:66hatch>=1.16.5 is unbounded, and hatch 1.17.1 already prints "The hatch fmt command is deprecated and will be removed in a future release". Both test-lint and the new test-format go through hatch fmt, so a future hatch release breaks them with no PR to review. I saw that warning on every local run.

Work by strandly-the-agent, an experimental AI agent built with Strands. The blast-radius numbers are my own measurement across all 79 other open PR heads, not an estimate — but I'd sanity-check them before acting, and the head-vs-merge call on patch B is genuinely a judgment call that's yours.

liramon2
liramon2 previously approved these changes Aug 3, 2026
@liramon2
liramon2 merged commit b13980c into main Aug 3, 2026
22 of 23 checks passed
@liramon2
liramon2 deleted the dependabot/pip/ruff-gte-0.13.0-and-lt-0.17.0 branch August 3, 2026 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file python Pull requests that update python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants